﻿using cs_dame.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs_dame.Controler
{
    class SpielfeldAnalysierer
    {
        private int groesse;
        private ISpielstand spielstand;

        public SpielfeldAnalysierer(int groesse, ISpielstand spielstand)
        {
            this.groesse = groesse;
            this.spielstand = spielstand;
        }

        public bool HatSpielerVerloren(bool isWeiss)
        {
            return !(KannJemandVonFarbeSchlagen(isWeiss) || kannJemandVonFarbeSpielen(isWeiss));
        }

        public bool IsAuswahlStartKnotenMoeglich(int x, int y, bool isWeiss)
        {
            if(IsGegner(x,y,isWeiss)) return false;
            bool isSchlagenFuerFarbeMoeglich = KannJemandVonFarbeSchlagen(isWeiss);
            if (isSchlagenFuerFarbeMoeglich)
            {
                if (IsDame(x,y))
                {
                    return KannDameSchlagen(x, y,isWeiss);
                }
                else
                {
                    return KannNormalerSteinSchlagen(x, y, isWeiss);
                }
            }
            else
            {
                if (IsDame(x, y))
                {
                    return KannDameZiehen(x, y);
                }
                else
                {
                    return KannNormalZiehen(x, y, isWeiss);
                }
            }
        }

        public bool isAuswahlZielMoeglich(int xStart, int yStart, int xZiel, int yZiel, bool isWeiss)
        {
            bool isAuswahlDame = IsDame(xStart, yStart);
            bool isAuswahlNormal = IsNormalStein(xStart, yStart);
            if (isAuswahlDame)
            {
                return isZielFuerDameErreichbar(xStart, yStart, xZiel, yZiel, isWeiss);
            }
            if (isAuswahlNormal)
            {
                return isZielErreichbarFuerNormalStein(xStart, yStart, xZiel, yZiel, isWeiss);
            }
            return false;
        }

        public bool isZielErreichbarFuerNormalStein(int xStart, int yStart, int xZiel, int yZiel, bool isWeiss)
        {
            bool isXZielOkFuerNormalenZug;
            if (isWeiss) isXZielOkFuerNormalenZug = xZiel == xStart + 1;
            else isXZielOkFuerNormalenZug = xZiel == xStart - 1;
            if (isXZielOkFuerNormalenZug)
            {
           //     return (yZiel == yStart + 1) || (yZiel == yStart - 1);
                return yZiel == yStart;
            }
            else
            {
                if (xZiel == xStart + 2 && yZiel == yStart + 2)
                {
                    if (IsFrei(xZiel, yZiel) && IsGegner(xStart + 1, yStart + 1, isWeiss))
                    {
                        spielstand.setAlsFrei(xStart + 1, yStart + 1);
                        return true;
                    }
                }
                if (xZiel == xStart + 2 && yZiel == yStart - 2)
                {
                    if (IsFrei(xZiel, yZiel) && IsGegner(xStart + 1, yStart - 1, isWeiss))
                    {
                        spielstand.setAlsFrei(xStart + 1, yStart - 1);
                        return true;
                    }
                }
                if (xZiel == xStart - 2 && yZiel == yStart + 2)
                {
                    if (IsFrei(xZiel, yZiel) && IsGegner(xStart - 1, yStart + 1, isWeiss))
                    {
                        spielstand.setAlsFrei(xStart - 1, yStart + 1);
                        return true;
                    }
                }
                if (xZiel == xStart - 2 && yZiel == yStart - 2)
                {
                    if (IsFrei(xZiel, yZiel) && IsGegner(xStart - 1, yStart - 1, isWeiss))
                    {
                        spielstand.setAlsFrei(xStart - 1, yStart - 1);
                        return true;
                    }
                }
                return false;
            }

        }

        public bool isZielFuerDameErreichbar(int xStart, int yStart, int xZiel, int yZiel, bool isWeiss)
        {
            return isZielFuerDameErreichbar(xStart,yStart,xZiel,yZiel,isWeiss,1,1) ||
                    isZielFuerDameErreichbar(xStart,yStart,xZiel,yZiel,isWeiss,1,-1) ||
                    isZielFuerDameErreichbar(xStart,yStart,xZiel,yZiel,isWeiss,-1,1) ||
                    isZielFuerDameErreichbar(xStart,yStart,xZiel,yZiel,isWeiss,-1,-1) ;

        }

        public bool isZielFuerDameErreichbar(int xStart, int yStart, int xZiel, int yZiel, bool isWeiss, int incrX, int incrY)
        {
            if(xZiel == xStart + incrX && yZiel == yStart + incrY){
                return IsFrei(xZiel, yZiel);
            }

            else
            {
                int j = xStart += incrX;
                int k = yStart += incrY;
                while (IsFrei(j, k))
                {
                    j += incrX;
                    k += incrY;
                }
                if (IsUnerreichbar(j, k)) return false;
                if (IsGegner(j, k, isWeiss) && IsFrei(j + incrX, k + incrY))
                {
                    spielstand.setAlsFrei(j, k);
                    return true;
                }
                return false;
            }
        }

        public bool KannJemandVonFarbeSchlagen(bool isWeiss)
        {
            for(int i = 0; i < groesse; i++)
            {
                for(int j = 0; j < groesse; j++)
                {
                    Spielsteine status = spielstand.getFeldStatus(i, j);
                    if (isWeiss)
                    {
                        if ((status == Spielsteine.DAMEWEISS && KannDameSchlagen(i, j, true)) ||
                            (status == Spielsteine.STEINWEISS && KannNormalerSteinSchlagen(i, j, true)) ) return true;
                    }
                    else
                    {
                        if ((status == Spielsteine.STEINSCHWARZ && KannNormalerSteinSchlagen(i, j, false)) ||
                            (status == Spielsteine.DAMESCHWARZ && KannDameSchlagen(i, j, false)) ) return true;
                    }
                }
            }
            return false;
        }

        public bool kannJemandVonFarbeSpielen(bool isWeiss)
        {
            for (int i = 0; i < groesse; i++)
            {
                for (int j = 0; j < groesse; j++)
                {
                    if (IsEigener(i, j, isWeiss))
                    {
                        if (IsDame(i, j))
                        {
                            if (KannDameSchlagen(i, j, isWeiss) || KannDameZiehen(i, j)) return true;
                        }
                        else
                        {
                            if (KannNormalerSteinSchlagen(i, j, isWeiss) || KannNormalZiehen(i, j, isWeiss)) return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool KannNormalZiehen(int x, int y, bool isWeiss)
        {
            int xNeu;
            if (isWeiss) xNeu = x++;
            else xNeu = x--;
            return IsFrei(xNeu, y + 1) || IsFrei(xNeu, y - 1); 
        }

        public bool KannDameZiehen(int x, int y)
        {
            return IsFrei(x + 1, y + 1) || 
                    IsFrei(x - 1, y - 1) || 
                    IsFrei(x - 1, y + 1) || 
                    IsFrei(x + 1, y - 1);
        }

        public bool KannNormalerSteinSchlagen(int x, int y, bool isWeiss)
        {
            if(  IsGegner(x+1,y-1,isWeiss)&& IsFrei(x+2,y-2)  ||
                (IsGegner(x+1,y+1,isWeiss)&& IsFrei(x+2,y+2)) ||
                (IsGegner(x-1,y-1,isWeiss)&& IsFrei(x-2,y-2)) ||
                (IsGegner(x-1,y+1,isWeiss)&& IsFrei(x-2,y+2)) ) return true;
            return false;
        }

        public bool KannDameSchlagen(int x, int y, bool isWeiss)
        {
            return KannDameSchlagen(x, y, isWeiss, 1, 1) || 
                    KannDameSchlagen(x, y, isWeiss, 1, -1) || 
                    KannDameSchlagen(x, y, isWeiss, -1, -1) || 
                    KannDameSchlagen(x, y, isWeiss, -1, 1);
        }

        public bool KannDameSchlagen(int x, int y, bool isWeiss, int incrX, int incrY)
        {
            int j = x + incrX;
            int k = y + incrY;
            while (IsFrei(j, k))
            {
                j += incrX;
                k += incrY;
            }
            if (IsGegner(j, k, isWeiss) && IsFrei(j + incrX, k + incrY)) return true;
            return false;
        }

        public bool IsGegner(int x, int y, bool isWeiss)
        {
            Spielsteine status = spielstand.getFeldStatus(x,y);
            if (!isWeiss && (status == Spielsteine.DAMEWEISS || status == Spielsteine.STEINWEISS)) return true;
            if (isWeiss && (status == Spielsteine.DAMESCHWARZ || status == Spielsteine.STEINSCHWARZ)) return true;
            return false;
        }

        public bool IsEigener(int x, int y, bool isWeiss)
        {
            Spielsteine status = spielstand.getFeldStatus(x, y);
            if (isWeiss && (status == Spielsteine.DAMEWEISS || status == Spielsteine.STEINWEISS)) return true;
            if (!isWeiss && (status == Spielsteine.DAMESCHWARZ || status == Spielsteine.STEINSCHWARZ)) return true;
            return false;
        }

        public bool IsFrei(int x, int y)
        {
            if (spielstand.getFeldStatus(x, y) == Spielsteine.FREI) return true;
            return false;
        }

        public bool IsDame(int x, int y)
        {
            Spielsteine status = spielstand.getFeldStatus(x, y);
            if (status == Spielsteine.DAMEWEISS || status == Spielsteine.DAMEWEISS) return true;
            return false;
        }

        public bool IsNormalStein(int x, int y)
        {
            Spielsteine status = spielstand.getFeldStatus(x, y);
            if (status == Spielsteine.STEINSCHWARZ || status == Spielsteine.STEINWEISS) return true;
            return false;
        }

        public bool IsUnerreichbar(int x, int y)
        {
            Spielsteine status = spielstand.getFeldStatus(x, y);
            if (status == Spielsteine.UNERREICHBAR) return true;
            return false;
        }
    }
}
